#ifndef _STL_UTIL_SELECT_H_
#define _STL_UTIL_SELECT_H_

#include "./stl_util_define.h"
#include "./container_insert.h"

namespace Holders {
				
	/*!
	auxiliary function
	*/
	template <class Set, class Iter, class Func>
		inline Set& select( Set& list, Iter begin, Iter end, const Func &func ) {
			for(Iter i = begin; i != end ; ++i)
				if( func(*i) )
					list, (*i); // insertion
					
			return list;
		};

	/*!
		function for selecting each item in a container, thus returning a new container
		with the valid itens.
		\param list the desired container to be tested
		\param func the function desired to use in each object
		\return a new container, sub-set of the original container
		\sa Set& apply( Set &list, const Func &func );
		\code
		deque< int > list;
		list, 1, 2, 3;
				
		cout << list << endl;						// prints [ 1 2 3 ]
		cout << select( asdf, Even ) << endl;	// prints [ 2 ]
		cout << list << endl;						// prints [ 1 2 3 ]
		\endcode
		\code
		// if using Lambda functions
		deque< double > list;
		list, 1.0, 2.0, 3.0;
				
		cout << list << endl;										// prints [ 1.0 2.0 3.0 ]
		Lambda< Var > x = Var();
		cout << check( asdf, 2 * x >= Ctt(3.0) ) << endl;	// prints [ 2.0 3.0 ]
		cout << list << endl;										// prints [ 1.0 2.0 3.0 ]
		\endcode
	*/
	template <class Set, class Func>
		Set select( const Set &list, const Func &func ) {
			Set ret;
			return select( ret, list.begin(), list.end(), func );

			//Set ret;
			//		
			//typename Set::iterator i = list.begin();
			//typename Set::iterator end = list.end();
			//		
			//for(; i != end ; ++i) {
			//	if( func(*i) ){
			//		ret.push_back(*i);
			//	}
			//}
			//		
			//return ret;
					
		};
				
	//! holder class for select.
	/*!
		class for calling select with operator().
	*/
	template <class Set, class Func>
		class SelectHolder{
		protected:
			/*! 1st parameter for check() */
			Set list;
			/*! 2nd parameter for check() */
			Func func;
		public:
			/*!
				constructor
				\param list 1st parameter for select()
				\param func 2nd parameter for select()
				\sa Set select( const Set &list, const Func &func );
			*/
			SelectHolder( const Set &list, const Func &func ): list(list), func(func) {};
			/*!
				copy constructor
				\param org the original object
				\sa SelectHolder( const Set &list, const Func &func );
			*/
			SelectHolder( const SelectHolder &org ): list(org.list), func(org.func) {};
			/*!
				operator for using the select with the parameters defined
				by its attributes.
				\return the same return as select().
				\sa Set select( const Set &list, const Func &func );
			*/
			inline Set operator()() {
				return select( list, func );
			};
		};
			
	/*!
		Function for creating a SelectHolder without telling
		the template parameters.
		\param list 1st parameter for select()
		\param func 2nd parameter for select()
		\sa Set select( const Set &list, const Func &func );
		\return a reference to the created object.
	*/
	template <class Set, class Func>
		inline SelectHolder<Set,Func>& Selecter( const Set &list, const Func &func ){
			return * ( new SelectHolder<Set,Func>( list, func ) );
		};
				
};

#endif // _STL_UTIL_SELECT_H_
